package com.ruoyi.binance.task;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONArray;
import com.ruoyi.binance.api.KlinesApi;
import com.ruoyi.binance.domain.Binance15macd;
import com.ruoyi.binance.domain.BinanceMinAverage;
import com.ruoyi.binance.domain.BinanceMinKConf;
import com.ruoyi.binance.mapper.Binance15macdMapper;
import com.ruoyi.binance.mapper.BinanceMinKMapper;
import com.ruoyi.binance.service.IBinance15macdService;
import com.ruoyi.binance.service.IBinance15minKService;
import com.ruoyi.binance.service.IBinanceMinKConfService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

@Component
public class Min15KTask {

    private static final Logger log = LoggerFactory.getLogger(Min15KTask.class);
    @Autowired
    private IBinance15minKService binance15minKService;
    @Autowired
    private IBinanceMinKConfService binanceMinKConfService;
    @Autowired
    private Binance15macdMapper binance15macdMapper;
    @Autowired
    private BinanceMinKMapper binanceMinKMapper;

    @Scheduled(cron = "0 0/1 * * * ?")
    public void min15k() {
        try {
            log.info("15分时K线定时任务----------------------开始");
            List<BinanceMinKConf> priceMonitorings = binanceMinKConfService.selectBinanceMinKConfList(new BinanceMinKConf());
            for (BinanceMinKConf bean : priceMonitorings) {
                JSONArray jsonArray = KlinesApi.min15K(bean.getCode(), null, null);
                if (jsonArray.isEmpty()) {
                    continue;
                }
                binance15minKService.saveOrUpdateMinK(bean.getCode(), jsonArray);
                Date time = jsonArray.getJSONArray(jsonArray.size() - 1).getDate(0);
                BigDecimal close = jsonArray.getJSONArray(jsonArray.size() - 1).getBigDecimal(4);
                Date closeTime = jsonArray.getJSONArray(jsonArray.size() - 1).getDate(6);
                String code = bean.getCode();
                //计算15分MACD
                //计算12周期EMA（快线）   计算26周期EMA（慢线）  计算差离值（DIF）
                BigDecimal ema12 = null;
                BigDecimal lastEma12 = null;
                BigDecimal ema26 = null;
                BigDecimal lastEma26 = null;
                BigDecimal dif = null;
                BigDecimal lastDea = null;
                BigDecimal dea = null;
                BigDecimal bar = null;
                Date lastTime = DateUtil.offset(time, DateField.MINUTE, -15);
                Binance15macd last15macd = binance15macdMapper.selectBinance15macdByCodeAndLastTime(code, DateUtil.formatDateTime(lastTime));
                //当前EMA(12) = (当前15分钟收盘价 × 2/13) + (前一根K线EMA(12) × 11/13)
                if(last15macd == null || last15macd.getEma12() == null){
                    lastEma12 = binanceMinKMapper.selectMinsAveragePrice(code, "180");
                }else {
                    lastEma12 = last15macd.getEma12();
                }
                ema12 = close.multiply(new BigDecimal("2")).divide(new BigDecimal("13"), 10, RoundingMode.HALF_UP)
                        .add(lastEma12.multiply(new BigDecimal("11")).divide(new BigDecimal("13"), 10, RoundingMode.HALF_UP));
                //当前EMA(26) = (当前15分钟收盘价 × 2/27) + (前一根K线EMA(26) × 25/27)
                if(last15macd == null || last15macd.getEma26() == null){
                    lastEma26 = binanceMinKMapper.selectMinsAveragePrice(code, "390");
                }else {
                    lastEma26 = last15macd.getEma26();
                }
                ema26 = close.multiply(new BigDecimal("2")).divide(new BigDecimal("27"), 10, RoundingMode.HALF_UP)
                        .add(lastEma26.multiply(new BigDecimal("25")).divide(new BigDecimal("27"), 10, RoundingMode.HALF_UP));
                //DIF = EMA(12) - EMA(26)
                if(ema12 != null && ema26 != null){
                    dif = ema12.subtract(ema26);
                }
                //计算DIF的9周期DEA
                if (last15macd == null || last15macd.getDea() == null){
                    int i = binance15macdMapper.countDifIsNull(bean.getCode());
                    if(i >= 9){
                       lastDea = binance15macdMapper.selectAverageEma(bean.getCode());
                    }
                }else {
                    lastDea = last15macd.getDea();
                }
                //当前DEA = (当前DIF × 0.2) + (前一个DEA × 0.8)
                if(lastDea != null){
                    dea = dif.multiply(new BigDecimal("0.2")).add(lastDea.multiply(new BigDecimal("0.8")));
                }
                //BAR = (DIF - DEA)
                if(dea != null){
                    bar = dif.subtract(dea);
                }
                Binance15macd binance15macd = new Binance15macd();
                binance15macd.setCode(code);
                binance15macd.setTime(time);
                binance15macd.setEma12(ema12);
                binance15macd.setEma26(ema26);
                binance15macd.setDif(dif);
                binance15macd.setDea(dea);
                binance15macd.setBar(bar);
                binance15macd.setCloseTime(closeTime);
                binance15macd.setUpdateTime(new Date());
                int i = binance15macdMapper.updateBinance15macd(binance15macd);
                if (i == 0) {
                    binance15macd.setCreateTime(new Date());
                    binance15macdMapper.insertBinance15macd(binance15macd);
                }
            }
            log.info("15分时K线定时任务----------------------结束");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
